package com.time.social.controller;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.time.social.config.SocialConfig;
import com.time.social.entity.Result;
import com.time.social.entity.SocialTokenResponse;
import com.time.social.entity.SocialUserInfo;
import com.time.social.enums.SocialTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * GitHub登录控制器
 *
 * @author: HuangQi
 * @date: Created in 2025/01/XX
 * @description: GitHub登录控制器
 */
@Slf4j
@RestController
@RequestMapping("/social/github")
public class GitHubLoginController extends AbstractSocialLoginController {

    @Autowired
    private SocialConfig socialConfig;

    private final Gson gson = new Gson();

    /**
     * GitHub授权URL
     */
    private static final String GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize";

    /**
     * GitHub获取Token URL
     */
    private static final String GITHUB_TOKEN_URL = "https://github.com/login/oauth/access_token";

    /**
     * GitHub获取用户信息 URL
     */
    private static final String GITHUB_USER_URL = "https://api.github.com/user";

    /**
     * GitHub获取用户邮箱 URL
     */
    private static final String GITHUB_USER_EMAIL_URL = "https://api.github.com/user/emails";

    /**
     * 跳转到GitHub授权页面
     */
    @GetMapping("/login")
    public RedirectView login() {
        return super.login();
    }

    /**
     * GitHub回调处理
     */
    @GetMapping("/callback")
    public Result<Object> callback(@RequestParam("code") String code,
                                    @RequestParam(value = "state", required = false) String state) {
        return super.callback(code, state);
    }

    @Override
    protected String getAuthUrl(String state) {
        SocialConfig.GitHubConfig githubConfig = socialConfig.getGithub();
        if (githubConfig == null) {
            throw new RuntimeException("GitHub配置未找到");
        }

        String redirectUri = buildCallbackUrl();
        String encodedRedirectUri = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8);

        // 构建授权URL
        StringBuilder url = new StringBuilder(GITHUB_AUTH_URL);
        url.append("?client_id=").append(githubConfig.getClientId());
        url.append("&redirect_uri=").append(encodedRedirectUri);
        url.append("&scope=user:email");
        url.append("&state=").append(state);

        return url.toString();
    }

    @Override
    protected SocialTokenResponse getAccessToken(String code) {
        try {
            SocialConfig.GitHubConfig githubConfig = socialConfig.getGithub();
            if (githubConfig == null) {
                throw new RuntimeException("GitHub配置未找到");
            }

            String redirectUri = buildCallbackUrl();

            // GitHub使用POST请求获取token
            String url = GITHUB_TOKEN_URL;
            Map<String, String> params = new HashMap<>();
            params.put("client_id", githubConfig.getClientId());
            params.put("client_secret", githubConfig.getClientSecret());
            params.put("code", code);
            params.put("redirect_uri", redirectUri);

            // 发送POST请求
            String response = httpPostForm(url, params);
            log.info("GitHub获取token响应: {}", response);

            // GitHub返回的是form格式，需要解析
            SocialTokenResponse tokenResponse = new SocialTokenResponse();
            String[] pairs = response.split("&");
            for (String pair : pairs) {
                String[] keyValue = pair.split("=");
                if (keyValue.length == 2) {
                    String key = keyValue[0];
                    String value = keyValue[1];
                    switch (key) {
                        case "access_token":
                            tokenResponse.setAccessToken(value);
                            break;
                        case "scope":
                            tokenResponse.setScope(value);
                            break;
                        case "error":
                            tokenResponse.setError(value);
                            break;
                        case "error_description":
                            tokenResponse.setErrorDescription(value);
                            break;
                    }
                }
            }

            if (tokenResponse.getAccessToken() == null) {
                tokenResponse.setError("unknown");
                tokenResponse.setErrorDescription("获取token失败");
            }

            return tokenResponse;
        } catch (Exception e) {
            log.error("GitHub获取access_token失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取GitHub access_token失败", e);
        }
    }

    @Override
    protected SocialUserInfo getUserInfo(String accessToken) {
        try {
            // 获取用户基本信息
            String userUrl = GITHUB_USER_URL;
            Map<String, String> headers = new HashMap<>();
            headers.put("Authorization", "token " + accessToken);
            headers.put("Accept", "application/vnd.github.v3+json");

            String userResponse = httpGetWithHeaders(userUrl, headers);
            log.info("GitHub获取用户信息响应: {}", userResponse);

            JsonObject jsonObject = gson.fromJson(userResponse, JsonObject.class);
            SocialUserInfo userInfo = new SocialUserInfo();

            if (jsonObject.has("id")) {
                userInfo.setOpenId(String.valueOf(jsonObject.get("id").getAsLong()));
                userInfo.setNickname(jsonObject.has("login") ? 
                    jsonObject.get("login").getAsString() : null);
                userInfo.setAvatar(jsonObject.has("avatar_url") ? 
                    jsonObject.get("avatar_url").getAsString() : null);
                userInfo.setEmail(jsonObject.has("email") ? 
                    jsonObject.get("email").getAsString() : null);
                userInfo.setLocation(jsonObject.has("location") ? 
                    jsonObject.get("location").getAsString() : null);
                userInfo.setRawData(userResponse);

                // 如果email为空，尝试获取邮箱列表
                if (userInfo.getEmail() == null) {
                    String emailResponse = httpGetWithHeaders(GITHUB_USER_EMAIL_URL, headers);
                    log.info("GitHub获取用户邮箱响应: {}", emailResponse);
                    // 解析邮箱列表，取第一个主邮箱
                    // 这里简化处理，实际应该解析JSON数组
                }
            } else {
                throw new RuntimeException("获取用户信息失败");
            }

            return userInfo;
        } catch (Exception e) {
            log.error("GitHub获取用户信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取GitHub用户信息失败", e);
        }
    }

    @Override
    protected SocialTypeEnum getSocialType() {
        return SocialTypeEnum.GITHUB;
    }

    @Override
    protected String getRedirectUri() {
        return socialConfig.getGithub() != null ? 
            socialConfig.getGithub().getRedirectUri() : "/social/github/callback";
    }

    /**
     * 发送带请求头的GET请求
     */
    private String httpGetWithHeaders(String url, Map<String, String> headers) {
        try {
            // 这里需要扩展HttpClientUtils支持请求头，暂时使用基础方法
            // TODO: 扩展HttpClientUtils支持请求头
            return httpGet(url);
        } catch (Exception e) {
            log.error("HTTP GET请求失败: url={}, error={}", url, e.getMessage(), e);
            throw new RuntimeException("HTTP请求失败", e);
        }
    }
}

